package com.ruoyi.scheme.service.decision.Impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.scheme.dto.ErsPatchAttributesDto;
import com.ruoyi.scheme.mapper.DecisionMakingMapper;
import com.ruoyi.scheme.pojo.Plant;
import com.ruoyi.scheme.pojo.PlatFormAndSlopeEntity;
import com.ruoyi.scheme.pojo.RepairMeasure;
import com.ruoyi.scheme.service.decision.*;
import com.ruoyi.scheme.vo.DecisionMakingVO;
import org.kie.api.KieBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruoyi.scheme.enums.DecisionMakingEnum.*;

@Service
public class DecisionMakingServiceImpl implements DecisionMakingService {

    @Autowired
    private DataParserService dataParserService;

    @Autowired
    private DroolsRuleEngineService droolsRuleEngineService;

    @Autowired
    private Exp4jCalculationService exp4jCalculationService;

    @Autowired
    private QuantitativeFormulaService quantitativeFormulaService;

    @Autowired
    private DecisionMakingMapper decisionMakingMapper;

    @Autowired
    private KieBase kieBase;

    /**
     * 根据斑块属性生成基础生态修复方案 基础规则加部分扩展规则
     * @param patchId 斑块ID
     * @param optMeasures 可选措施
     * @param patchAttributesDto 斑块属性DTO
     * @return DecisionMakingVO
     */
    @Override
    public DecisionMakingVO generateDefaultScheme(Integer patchId, Integer optMeasures, ErsPatchAttributesDto patchAttributesDto) {
        //1.把Dto转成实体
        PlatFormAndSlopeEntity platFormAndSlopeEntity = dataParserService.parsePatchAttributes(patchAttributesDto);

        int locationType = platFormAndSlopeEntity.getLocation();

        //进行业务处理，获得预设规则
        List<RepairMeasure> preRepairMeasures = droolsRuleEngineService.executeRules(kieBase, locationType, platFormAndSlopeEntity);

        //添加扩展规则
        //1.定量施加有机肥
        //先从preRepairMeasures中汇找到措施类型为FERTILIZATION的措施
        for(RepairMeasure repairMeasure : preRepairMeasures){
            if(repairMeasure.getRepairScheme() != null){
                // 检查repairScheme中是否包含organic_fertilizer的JSON数据
                JSONObject schemeJson = repairMeasure.getRepairScheme();
                if(schemeJson.containsKey(ORGANICFERTILIZER.getDescription())){
                    //应用定量公式服务并更新repairMeasure对象
                    RepairMeasure updatedMeasure = quantitativeFormulaService.applyQuantitativeFormulas(repairMeasure, platFormAndSlopeEntity);
                    // 将更新后的方案设置回原对象
                    repairMeasure.setRepairScheme(updatedMeasure.getRepairScheme());
                }
            }
        }

        //2.可选型措施
        if(optMeasures == null){
            JSONObject measureJson4 = new JSONObject();
            measureJson4.put(MIXMEASURE.getDescription(), METHOD_4.getDescription());
            preRepairMeasures.add(new RepairMeasure(null, patchId, measureJson4, LocalDateTime.now(), LocalDateTime.now()));
        }else {
            switch (optMeasures) {
                case 1:
                    JSONObject measureJson = new JSONObject();
                    measureJson.put(MIXMEASURE.getDescription(), METHOD_1.getDescription());
                    preRepairMeasures.add(new RepairMeasure(null, patchId, measureJson, LocalDateTime.now(), LocalDateTime.now()));
                    break;
                case 2:
                    JSONObject measureJson2 = new JSONObject();
                    measureJson2.put(MIXMEASURE.getDescription(), METHOD_2.getDescription());
                    preRepairMeasures.add(new RepairMeasure(null, patchId, measureJson2, LocalDateTime.now(), LocalDateTime.now()));
                    break;
                case 3:
                    JSONObject measureJson3 = new JSONObject();
                    measureJson3.put(MIXMEASURE.getDescription(), METHOD_3.getDescription());
                    preRepairMeasures.add(new RepairMeasure(null, patchId, measureJson3, LocalDateTime.now(), LocalDateTime.now()));
                    break;
                default:
                    JSONObject measureJson4 = new JSONObject();
                    measureJson4.put(MIXMEASURE.getDescription(), METHOD_4.getDescription());
                    preRepairMeasures.add(new RepairMeasure(null, patchId, measureJson4, LocalDateTime.now(), LocalDateTime.now()));
                    break;
            }
        }

        // 创建一个新的JSONObject来存储修复措施列表
        JSONObject combinedScheme = new JSONObject();
        // 将preRepairMeasures列表添加到JSONObject中
        combinedScheme.put("default:", preRepairMeasures);
        System.out.println("default: " + combinedScheme);
        
        RepairMeasure finalRepairMeasure = RepairMeasure.builder()
                .patchId(patchId)
                .repairScheme(combinedScheme)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        // 将整合后的方案插入数据库，并获取自动生成的schemeId
        decisionMakingMapper.insertRepairMeasure(finalRepairMeasure);
        Integer schemeId = finalRepairMeasure.getSchemeId();

        return DecisionMakingVO.builder()
                .schemeId(schemeId)
                .repairSchemeName(DEFAULT.getDescription())
                .repairSchemeDetails(combinedScheme)
                .build();
    }

    /**
     * 生成作播种生态修复方案
     * @param patchAttributesDto
     * @param plantName
     * @param schemeId
     * @return
     */
    @Override
    public DecisionMakingVO singleGrassScheme(ErsPatchAttributesDto patchAttributesDto, String plantName, Integer schemeId) {
        System.out.println("开始执行单作方案，植物名称: " + plantName);

        // 获取数据库中的修复方案
        RepairMeasure repairMeasure = decisionMakingMapper.selectRepairMeasureById(schemeId);
        JSONObject repairScheme = repairMeasure.getRepairScheme();

        // 执行业务逻辑处理，获取处理后的plant对象
        Plant plant = processSingleGrassBusinessLogic(patchAttributesDto, plantName);
        System.out.println("业务逻辑处理后，植物密度: " + plant.getPlantDensity() + ", 植物类型: " + plant.getPlantType());

        // 确保plantDensity不为null
        Double finalPlantDensity = plant.getPlantDensity();
        if (finalPlantDensity == null) {
            System.out.println("警告: 植物密度仍然为null，使用默认值");
            finalPlantDensity = 0.5 / 667; // 默认草本密度
        }

        //将计算得到的种植密度添加到repairScheme中
        if(plant.getPlantType() != null && plant.getPlantType().equals(1)) {
            //木本植物
            repairScheme.put(SINGLE.getDescription(), ADVICE_1.getDescription()+ plant.getPlantName() + finalPlantDensity + " kg");
        }else {
            repairScheme.put(SINGLE.getDescription(), ADVICE_2.getDescription()+ plant.getPlantName() + finalPlantDensity + "株");
        }

//        String repairSchemeStr = repairScheme instanceof JSONObject ? repairScheme.toString() : repairScheme.toString();
        boolean updateResult = decisionMakingMapper.updateRepairMeasureSchemeById(schemeId, repairScheme);

        Map<String, Object> repairSchemeMap = new HashMap<>();

        if(updateResult) {
            repairSchemeMap.put(FINAL.getDescription(), repairScheme);
        }else {
            repairSchemeMap.put(ERROR.getDescription(), UPDATE_FAILED.getDescription());
        }

        return DecisionMakingVO.builder()
                .schemeId(schemeId)
                .repairSchemeName(SINGLE.getDescription())
                .repairSchemeDetails(repairSchemeMap)
                .build();
    }

    /**
     * 生成草料混播播种生态修复方案
     * @param patchAttributesDto
     * @param plantMix
     * @param schemeId
     * @return
     */
    @Override
    public DecisionMakingVO mixGrassScheme(ErsPatchAttributesDto patchAttributesDto, String plantMix, Integer schemeId) {
        System.out.println("开始执行混播方案，植物混播配置: " + plantMix);

        RepairMeasure repairMeasure = decisionMakingMapper.selectRepairMeasureById(schemeId);
        Object repairScheme = repairMeasure.getRepairScheme();

        Map<String, Double> plantDensityResults = new HashMap<>();

        //如果为空，采用默认值
        if(plantMix == null || plantMix.isEmpty()){
            System.out.println("植物混播配置为空，使用默认值");
            plantDensityResults.put(DEFAULT_GRASS.getDescription(), 0.0);
            plantDensityResults.put("无芒麦草", 0.6);
            plantDensityResults.put("苜蓿", 0.4);

            plantDensityResults.put(DEFAULT_WOOD.getDescription(), 0.0);
            plantDensityResults.put("沙棘", 0.6);
            plantDensityResults.put("油松", 0.4);
        }

        //把plantMix字符串（格式: "plantName1:density1,plantName2:density2,..."）转换为Map
        Map<String, Double> plantMixMap = new HashMap<>();
        String[] plantEntries = plantMix.split(",");
        for(String entry : plantEntries){
            String[] parts = entry.split(":");
            if(parts.length == 2){
                String plantName = parts[0].trim();
                Double proportion = Double.parseDouble(parts[1].trim());
                plantMixMap.put(plantName, proportion);
            }
        }

        //检查plantMixMap中所有植物比例之和是否为1.0
        double totalProportion = plantMixMap.values().stream().mapToDouble(Double::doubleValue).sum();
        Map<String, Object> errorMap = new HashMap<>();
        errorMap.put("请检查输入参数,所有参数之和必须为100%: ", totalProportion);
        if(Math.abs(totalProportion - 1.0) > 0.0001){
            return DecisionMakingVO.builder()
                    .schemeId(schemeId)
                    .repairSchemeName(MIXED.getDescription())
                    .repairSchemeDetails(errorMap)
                    .build();
        }

        //遍历混播植物列表，处理每种植物
        for(Map.Entry<String, Double> entry : plantMixMap.entrySet()){
            String plantName = entry.getKey();
            Double proportion = entry.getValue();
            System.out.println("处理混播植物: " + plantName + ", 比例: " + proportion);

            Plant plant = processSingleGrassBusinessLogic(patchAttributesDto, plantName);
            System.out.println("植物业务逻辑处理后，密度: " + plant.getPlantDensity() + ", 类型: " + plant.getPlantType());

            //计算混播后的种植密度，添加null值检查
            Double plantDensity = plant.getPlantDensity();
            Double mixedPlantDensity;

            if(plantDensity == null){
                System.out.println("植物密度为null，使用默认值，植物名称: " + plantName);
                // 根据植物类型设置默认值
                if (plant.getPlantType() != null && plant.getPlantType().equals(2)) {
                    mixedPlantDensity = 0.5 * proportion; // 木本植物默认密度
                } else {
                    mixedPlantDensity = (0.5 / 667) * proportion; // 草本植物默认密度
                }
            } else {
                mixedPlantDensity = plantDensity * proportion;
            }

            plantDensityResults.put(plantName, mixedPlantDensity);
            System.out.println("混播后植物密度: " + plantName + " = " + mixedPlantDensity);
        }

        //将混播结果添加到repairScheme中
        if(repairScheme instanceof JSONObject){
            JSONObject schemeJson = (JSONObject) repairScheme;
            schemeJson.put(MIXED_PLAN.getDescription(), ADVICE_3.getDescription() + plantDensityResults);
            // 将JSON对象转换为字符串格式存储
            repairScheme = schemeJson.toString();
        }

        // 更新数据库中的repairMeasure，确保传入的是字符串格式
        // 确保传入数据库时是字符串格式
        boolean updateResult = decisionMakingMapper.updateRepairMeasureSchemeById(schemeId, repairScheme);

        Map<String, Object> repairSchemeMap = new HashMap<>();
        if(updateResult) {
            repairSchemeMap.put(FINAL.getDescription(), repairScheme);
        }else {
            repairSchemeMap.put(ERROR.getDescription(), UPDATE_FAILED.getDescription());
        }

        return DecisionMakingVO.builder()
                .schemeId(schemeId)
                .repairSchemeName(MIXED.getDescription())
                .repairSchemeDetails(repairSchemeMap)
                .build();
    }

    /**
     * 执行单作植被修复方案的业务引擎处理
     * @param patchAttributesDto 斑块属性DTO
     * @param plantName 植物名称
     * @return 处理后的Plant对象
     */
    private Plant processSingleGrassBusinessLogic(ErsPatchAttributesDto patchAttributesDto, String plantName) {
        System.out.println("开始处理单作业务逻辑，植物名称: " + plantName);

        PlatFormAndSlopeEntity platFormAndSlopeEntity = dataParserService.parsePatchAttributes(patchAttributesDto);
        Plant plant = new Plant();
        plant.setPlantName(plantName);
        System.out.println("创建Plant对象，植物名称: " + plant.getPlantName());

        // 执行Drools规则计算种植密度
        plant = droolsRuleEngineService.executePlantDensityRules(kieBase, plant, platFormAndSlopeEntity);
        System.out.println("Drools规则执行后，植物密度: " + plant.getPlantDensity() + ", 植物类型: " + plant.getPlantType());

        // 计算定量播种量
        Double plantDensity = exp4jCalculationService.calculatePlantDensity(plant, platFormAndSlopeEntity);
        System.out.println("exp4j计算得到的植物密度: " + plantDensity);
        
        if (plantDensity != null) {
            plant.setPlantDensity(plantDensity);
            System.out.println("使用exp4j计算结果更新植物密度: " + plant.getPlantDensity());
        }
        
        // 确保plantDensity不为null
        if (plant.getPlantDensity() == null) {
            // 如果Drools规则和exp4j计算都没有设置密度，则设置默认值
            System.out.println("植物密度为null，根据植物类型设置默认值，当前植物类型: " + plant.getPlantType());
            if (plant.getPlantType() != null && plant.getPlantType().equals(2)) {
                plant.setPlantDensity(0.5); // 木本植物默认密度
                System.out.println("设置木本植物默认密度: 0.5");
            } else {
                plant.setPlantDensity(0.5 / 667); // 草本植物默认密度
                System.out.println("设置草本植物默认密度: 0.5/667");
            }
        }
        
        System.out.println("业务逻辑处理完成，最终植物密度: " + plant.getPlantDensity() + ", 植物类型: " + plant.getPlantType());

        return plant;
    }

}
